package org.ceteca.explica.server.common;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.ceteca.explica.core.ExplicaException;
import org.ceteca.explica.core.InterfaceErrors;
import org.ceteca.explica.core.common.BarcodeTypeOT;
import org.ceteca.explica.core.common.BaseVO;
import org.ceteca.explica.core.common.CommonManager;
import org.ceteca.explica.core.common.VatTypeOT;
import org.ceteca.explica.core.extTables.ExtTableException;
import org.ceteca.explica.core.extTables.ExtTableLN;
import org.ceteca.explica.core.extTables.ExtTableOT;
import org.ceteca.explica.core.util.OperationResult;
import org.ceteca.explica.server.ServerContext;
import org.ceteca.explica.server.common.bl.CommonBLL;
import org.ceteca.explica.server.util.db.CriteriaBean;
import org.ceteca.explica.core.util.FieldValue;
import org.ceteca.explica.server.util.db.InterfaceDB;




/**
 * @author Juan C. Díaz (juancarlosdiaz@ceteca.net) <br>
 *         Copyright (c) 2009 Fundación Centro Tecnolóxico da Carne
 * 
 * <br>
 * <br>
 *         This program is free software: you can redistribute it and/or modify
 *         it under the terms of the GNU General Public License as published by
 *         the Free Software Foundation, either version 3 of the License, or (at
 *         your option) any later version. <br/>
 *         This program is distributed in the hope that it will be useful, but
 *         WITHOUT ANY WARRANTY 
 *         <br>without even the implied warranty of
 *         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *         General Public License for more details. <br/>
 *         You should have received a copy of the GNU General Public License
 *         along with this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 */
public class CommonManagerImpl extends UnicastRemoteObject implements
		CommonManager {
	private static final long serialVersionUID = 123456789;

	public CommonManagerImpl() throws RemoteException {
		super();
	}

	public List queryBarcodeTypes(String fieldId, String value)
			throws RemoteException, ExplicaException {
		ArrayList<CriteriaBean> lCriteria = new ArrayList<CriteriaBean>();

		// Add the query criteria to the list
		if (fieldId != null && fieldId.length() > 0 && value != null
				&& value.length() > 0) {
			lCriteria.add(this.buildCriteria(fieldId, FieldValue.getFieldValue(
					BarcodeTypeOT.class, fieldId, value)));
		}

		return CommonBLL.getInstance().queryBarcodeTypes(lCriteria);
	}

	public OperationResult delBarcodeType(Long idBarcodeType)
			throws RemoteException, ExplicaException {
		return CommonBLL.getInstance().delBarcodeType(idBarcodeType);
	}

	public OperationResult delBarcodeTypes(ArrayList<Long> lSelBarcodeTypes)
			throws RemoteException, ExplicaException {
		return CommonBLL.getInstance().delBarcodeTypes(lSelBarcodeTypes);
	}

	public OperationResult saveBarcodeType(BarcodeTypeOT barcodeType)
			throws RemoteException, ExplicaException {
		return CommonBLL.getInstance().saveBarcodeType(barcodeType);
	}

	public BarcodeTypeOT getBarcodeType(Long idBarcodeType)
			throws RemoteException, ExplicaException {
		return CommonBLL.getInstance().getBarcodeType(idBarcodeType);
	}

	public List queryVatTypes(String fieldId, String value)
			throws RemoteException, ExplicaException {
		ArrayList<CriteriaBean> lCriteria = new ArrayList<CriteriaBean>();

		// Add the query criteria to the list
		if (fieldId != null && fieldId.length() > 0 && value != null
				&& value.length() > 0) {
			lCriteria.add(this.buildCriteria(fieldId, FieldValue.getFieldValue(
					VatTypeOT.class, fieldId, value)));
		}

		return CommonBLL.getInstance().queryVatTypes(lCriteria);
	}

	public OperationResult delVatType(Long idVatType) throws RemoteException,
			ExplicaException {
		return CommonBLL.getInstance().delVatType(idVatType);
	}

	public OperationResult delVatTypes(ArrayList<Long> lSelVatTypes)
			throws RemoteException, ExplicaException {
		return CommonBLL.getInstance().delVatTypes(lSelVatTypes);
	}

	public OperationResult saveVatType(VatTypeOT vatType)
			throws RemoteException, ExplicaException {
		return CommonBLL.getInstance().saveVatType(vatType);
	}

	public VatTypeOT getVatType(Long idVatType) throws RemoteException,
			ExplicaException {
		return CommonBLL.getInstance().getVatType(idVatType);
	}

	
	public ExtTableOT getExtensionTableDefinition(String codExtTable)
			throws RemoteException, ExtTableException {
		return ExtTableLN.getInstance()
				.getExtensionTableDefinition(codExtTable);
	}

	/**
	 * Return all the values stored for an extended item. Include all the fields
	 * defined for the extension table and their correspondent value (if anyone
	 * has been defined).
	 * 
	 * @param idValue
	 *            Long, internal id of the extended item.
	 * @param codExtTable
	 *            String, external code of the extension table.
	 * @return Map, set of all the extension fields and their values for the
	 *         extended item.
	 * @throws ExtTableException
	 *             , in case any error take place during the query operation.
	 */
	public Map getExtendedItemValues(Long idValue, String codExtTable)
			throws RemoteException, ExtTableException {
		return ExtTableLN.getInstance().getExtendedItemValues(idValue,
				codExtTable);
	}

	/**
	 * Update the value of all the extension fields defined for an extended
	 * item.
	 * 
	 * @param lExtFields
	 *            ArrayList, list of all the extension fields whose values must
	 *            be updated.
	 * @param idItem
	 *            long, internal id of the extended item.
	 * @return OperationResult, result of the save extended values operation.
	 * @throws ExtTableException
	 *             , in case any error take place during the update operation.
	 */
	public OperationResult saveExtendedItemValues(ArrayList lExtFields,
			long idItem) throws RemoteException, ExtTableException {
		return ExtTableLN.getInstance().saveExtendedItemValues(lExtFields,
				idItem);
	}

	/**
	 * Update the value of all the extension fields defined for an extended
	 * item.
	 * 
	 * @param mExtFields
	 *            Map, set of all the extension fields whose values must be
	 *            updated.
	 * @param idItem
	 *            long, internal id of the extended item.
	 * @throws ExtTableException
	 *             , in case any error take place during the update operation.
	 */
	public void saveExtendedItemValues(Map mExtFields, long idItem)
			throws RemoteException, ExtTableException {
		ExtTableLN.getInstance().saveExtendedItemValues(mExtFields, idItem);
	}

	private CriteriaBean buildCriteria(String fieldId, Object value) {
		CriteriaBean result = null;
		Object val = null;
		String op;

		if (value instanceof String) {
			op = InterfaceDB.SQL_OPERATOR_LIKE;
			val = new String("%" + value + "%");
		} else {
			op = InterfaceDB.SQL_OPERATOR_EQUAL;
			val = value;
		}

		// Add the query criteria to the list
		if (fieldId != null && fieldId.length() > 0 && val != null) {
			result = new CriteriaBean(fieldId, val, op, null, null, null);
		}

		return result;
	}

	
	public OperationResult delEntities(ArrayList<Long> sel, Class myClass)
			throws RemoteException, ExplicaException {

		return CommonBLL.getInstance().delEntities(sel, myClass);
	}

	public OperationResult delEntity(BaseVO b) throws RemoteException,
			ExplicaException {

		return CommonBLL.getInstance().delEntity(b);
	}

	public BaseVO getEntity(Long id, Class myClass) throws RemoteException,
			ExplicaException {

		return CommonBLL.getInstance().getEntity(id, myClass);
	}

	public List<BaseVO> queryEntities(String fieldId, String value,
			Class myClass) throws RemoteException, ExplicaException {
		ArrayList<CriteriaBean> lCriteria = new ArrayList<CriteriaBean>();
		if (fieldId != null && fieldId.length() > 0 && value != null
				&& value.length() > 0) {
			lCriteria.add(this.buildCriteria(fieldId, FieldValue.getFieldValue(
					myClass, fieldId, value)));
		}
		ArrayList<BaseVO> result = CommonBLL.getInstance().queryEntities(
				lCriteria, myClass);
		return result;
	}

	public OperationResult saveEntity(BaseVO entity) throws RemoteException,
			ExplicaException {

		return CommonBLL.getInstance().saveEntity(entity);
	}

	public List<BaseVO> queryEntities(String fieldId, BaseVO value,
			Class myClass) throws RemoteException, ExplicaException {
		
		
		ArrayList<CriteriaBean> lCriteria = new ArrayList<CriteriaBean>();
		if (fieldId != null && fieldId.length() > 0 && value != null) {
			// if (fieldId !=null && fieldId.length()>0){
			CriteriaBean c = this.buildCriteria(fieldId, value);
			// System.out.println("Building criteria: "+c.getCriteriaAsSql(true)+" "+c.getFieldValue().toString());
			lCriteria.add(c);
		}
		ArrayList<BaseVO> result = null;
		if (value != null)
			// System.out.println("Retriving result. Filtering by  "+value.getClass().getCanonicalName());
			result = CommonBLL.getInstance().queryEntities(lCriteria, myClass);
		// System.out.println(result.size()+" entities retrieved");
		return result;
	}

	public List<BaseVO> queryEntities(String hql)
			throws RemoteException, ExplicaException {

			return CommonBLL.getInstance().queryEntities(hql);
	}


	public BaseVO getEntity(String fieldId, String value, Class myClass) 
			throws RemoteException, ExplicaException {

		ArrayList<CriteriaBean> lCriteria = new ArrayList<CriteriaBean>();
		if (fieldId != null && fieldId.length() > 0 && value != null) {
			lCriteria.add(this.buildCriteria(fieldId, FieldValue.getFieldValue(
					myClass, fieldId, value)));
		}
		ArrayList<BaseVO> entities = CommonBLL.getInstance().queryEntities(
				lCriteria, myClass);
		if (entities == null || entities.size() != 1) {
			throw new ExplicaException(ServerContext.getInstance().getMsgCatalog().newResultMessage(InterfaceErrors.ERR_ENTITY_NOT_FOUND));
		}
		else {
			return entities.get(0);
		}
	}
	
	public OperationResult saveImage(String imgName, byte[] contents) 
		throws RemoteException, ExplicaException {
	
		ServerContext.getInstance().getLogger().debug("Saving image: " + imgName);
		return ServerContext.getInstance().saveImage(imgName, contents);
	}
}
